﻿using System;
using System.Collections.Generic;
using System.Linq;
using LayeredArchitectureSample.DataTransferObjects;
using LayeredArchitectureSample.Infrastructure;
using LayeredArchitectureSample.Infrastructure.Services;
using LayeredArchitectureSample.ServiceContracts;

namespace LayeredArchitectureSample.RandomDataProviders
{
    class RandomWareProvider : IRandomWareProvider
    {
        private readonly IServiceOperationInvoker<IRemoteWareRepository> _wareRepository;

        public RandomWareProvider(IServiceOperationInvoker<IRemoteWareRepository> wareRepository)
        {
            if (wareRepository == null) throw new ArgumentNullException("wareRepository");

            _wareRepository = wareRepository;
        }

        /// <exception cref="CannotProvideRandomObjectException"></exception>
        public IEnumerable<WareUnitsCountedDto> GetRandomWares(int numberOfWares)
        {
            var random = new Random((int)DateTime.UtcNow.Ticks);

            var allWares = _wareRepository.Invoke(r => r.GetAll()).ToList();

            if (allWares.Count < numberOfWares)
            {
                throw new CannotProvideRandomObjectException("Failed to create random set of wares. The following number of wares is required to be present in repository: {0}. Please add them, then try again.".FormatWith(numberOfWares));
            }

            var wares = new HashSet<WareDto>(); // Yeah, no worries about the shuffling

            while (wares.Count < numberOfWares)
            {
                WareDto ware = allWares[random.Next(allWares.Count)];

                wares.Add(ware);
            }

            var waresWithQuantities = new List<WareUnitsCountedDto>();

            foreach (WareDto ware in wares)
            {
                int quantity = random.Next(1, 150);

                waresWithQuantities.Add(new WareUnitsCountedDto(quantity, ware));
            }

            return waresWithQuantities;
        }
    }
}